﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms.DataVisualization.Charting;
using Habanero.BO;
using Habanero.UI.Base;
using Habanero.UI.Win;
using UseCaseManager.BO;
using UseCaseManager.Logic;

namespace UseCaseManager.UI
{
    public class BurnDownChartControl : UserControlWin, IFormControl
    {
        //Assumes only one project loaded- i.e. all drops belong to one project.
        private Project _project = UseCaseManagerRegistry.CurrentProject;
        private BusinessObjectCollection<Drop> _drops = UseCaseManagerRegistry.Drops;
        private Chart chart;

        public BurnDownChartControl()
        {
            CreateChart();
            this.Controls.Add(chart);
        }

        public void CreateChart()
        {
            chart = new Chart();

            // Set chart title
            chart.Titles.Add("Title");
            chart.Titles[0].Text = _project.ProjectName;
            // Set chart title font
            chart.Titles[0].Font = new Font("Arial", 14, FontStyle.Bold);


            chart.Legends.Add("Default");
            chart.ChartAreas.Add("Default");

            const string seriesNameAssigned = "Assigned";
            const string seriesNameBaseline = "Baseline";
            const string seriesNameCompleted = "Completed";

            Series assigned = GetData(seriesNameAssigned);
            Series baseline = GetData(seriesNameBaseline);
            Series completed = GetData(seriesNameCompleted);

            assigned.LegendText = seriesNameAssigned;
            baseline.LegendText = seriesNameBaseline;
            completed.LegendText = seriesNameCompleted;

            assigned.ChartType = SeriesChartType.Line;
            baseline.ChartType = SeriesChartType.Line;
            completed.ChartType = SeriesChartType.Line;

            assigned.Color = Color.Blue;
            assigned.BorderWidth = 4;
            assigned.BorderColor = Color.Blue;
            assigned.BorderDashStyle = ChartDashStyle.Solid;

            baseline.Color = Color.Orange;
            baseline.BorderWidth = 4;
            baseline.BorderColor = Color.Orange;
            baseline.BorderDashStyle = ChartDashStyle.Solid;

            completed.Color = Color.Green;
            completed.BorderWidth = 4;
            completed.BorderColor = Color.Green;
            completed.BorderDashStyle = ChartDashStyle.Solid;

            chart.Series.Add(assigned);
            chart.Series.Add(baseline);
            chart.Series.Add(completed);

            chart.ChartAreas["Default"].AxisX.MajorGrid.LineColor = Color.DimGray;
            chart.ChartAreas["Default"].AxisY.MajorGrid.LineColor = Color.DimGray;

            chart.ChartAreas["Default"].BackColor = Color.LightGray;
            chart.ChartAreas["Default"].BackSecondaryColor = Color.White;
            chart.ChartAreas["Default"].BackGradientStyle = GradientStyle.TopBottom;

            chart.ChartAreas["Default"].AxisY.Maximum = (_project.PointsAssigned / 100 + 1) * 100;
            chart.ChartAreas["Default"].AxisY.Interval = 50;

            chart.ChartAreas["Default"].AxisX.Interval = 1;
            chart.ChartAreas["Default"].AxisX.IntervalType = DateTimeIntervalType.Weeks;
            chart.ChartAreas["Default"].AxisX.IntervalOffset = 1;
            chart.ChartAreas["Default"].AxisX.IntervalOffsetType = DateTimeIntervalType.Days;

            chart.ChartAreas["Default"].IsSameFontSizeForAllAxes = true;

            chart.Size = new Size(600, 600);
        }

        public List<DataItem> GetDataPoints(string seriesName)
        {
            int total;
            List<DataItem> data = new List<DataItem>();
            if (seriesName == "Assigned")
            {
                total = _project.PointsAssigned;
                foreach (Drop drop in _drops)
                {
                    total -= drop.PointsAssigned.Value;
                    data.Add(new DataItem(drop.EndDate.Value, total));
                }
            }
            if (seriesName == "Baseline")
            {
                total = _project.PointsBaseline;
                foreach (Drop drop in _drops)
                {
                    total -= drop.PointsBaseline.Value;
                    data.Add(new DataItem(drop.EndDate.Value, total));
                }
            }
            if (seriesName == "Completed")
            {
                total = _project.PointsAssigned;
                foreach (Drop drop in _drops)
                {
                    if (drop.PointsCompleted == 0 && drop.EndDate > DateTime.Now)
                    {
                        total -= drop.PointsAssigned.Value;
                    }
                    else
                    {
                        total -= drop.PointsCompleted.Value;
                    }
                    data.Add(new DataItem(drop.EndDate.Value, total));
                }
            }
            return data;
        }

        public class DataItem
        {
            public DateTime Date;
            public int Value;
            public DataItem(DateTime date, int value)
            {
                Date = date;
                Value = value;
            }
        }

        public Series GetData(string seriesName)
        {
            Series series = new Series();

            List<int> yPoints = new List<int>();
            List<DateTime> xPoints = new List<DateTime>();

            List<DataItem> dropData = GetDataPoints(seriesName);
            foreach (DataItem dataItem in dropData)
            {
                xPoints.Add(dataItem.Date);
                yPoints.Add(dataItem.Value);
            }
            series.Points.DataBindXY(xPoints, yPoints);
            return series;
        }

        /// <summary>
        /// Called whenever the control is placed on a form by the menu system.  Put any initialisation
        /// code in here that must be run whenever the form is displayed.
        /// </summary>
        public void SetForm(IFormHabanero form)
        {
        }
    }
}
